package concurrent.lock;

import org.junit.Test;

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReentrantReadWriteLockTest {

    private AtomicInteger writeCount = new AtomicInteger();
    private AtomicInteger readCount = new AtomicInteger();

    @Test
    public void simpleTest() {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);

        Runnable writeRunnable = new Runnable() {
            ThreadLocalRandom random = ThreadLocalRandom.current();

            @Override
            public void run() {
                while (true) {
                    ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
                    writeLock.lock();
                    try {
                        writeCount.incrementAndGet();
//                        System.err.println("获取到写锁");
//                        int r = random.nextInt(1000);
//                        try {
//                            Thread.sleep(r);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                        System.err.println("解除写锁");
                    } finally {
                        writeLock.unlock();
                    }
                }
            }
        };

        Runnable readRunnable = new Runnable() {
            ThreadLocalRandom random = ThreadLocalRandom.current();

            @Override
            public void run() {
                while (true) {
                    ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
                    readLock.lock();
                    try {
                        readCount.incrementAndGet();
//                        System.out.println(Thread.currentThread().getName() + "获取到读锁");
//                        int r = random.nextInt(500);
//                        try {
//                            Thread.sleep(r);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                        System.out.println(Thread.currentThread().getName() + "解除读锁");
                    } finally {
                        readLock.unlock();
                    }
                }
            }
        };

        Thread writeThread = new Thread(writeRunnable);
        Thread readThread = new Thread(readRunnable, "1号");
        Thread readThread2 = new Thread(readRunnable, "2号");
        Thread readThread3 = new Thread(readRunnable, "3号");

        writeThread.start();
        readThread.start();
        readThread2.start();
        readThread3.start();

        LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(10));
        System.out.println("写次数：" + writeCount.get() + "，读次数：" + readCount.get());
    }
}
